// @ts-nocheck
// <div id="app">Hello Vue</div>

// {
//   tag: 'div',
//   attrs: [{id: 'app'}],
//   children: [{tag: null, text: hello},{tag: 'h'}]
// }

const attribute =
  /^\s*([^\s"'<>\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/;
const dynamicArgAttribute =
  /^\s*((?:v-[\w-]+:|@|:|#)\[[^=]+?\][^\s"'<>\/=]*)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/;
const ncname = `[a-zA-Z_][\\-\\.0-9_a-zA-Z]*`;
const qnameCapture = `((?:${ncname}\\:)?${ncname})`;
const startTagOpen = new RegExp(`^<${qnameCapture}`);
const startTagClose = /^\s*(\/?)>/;
const endTag = new RegExp(`^<\\/${qnameCapture}[^>]*>`);
const defaultTagRE = /\{\{((?:.|\r?\n)+?)\}\}/g; //{{}}

// 遍历
// 创建ast对象
function createAstElement(tag, attrs) {
  return {
    tag,
    attrs,
    children: [], // 子节点
    type: 1,
    parent: null,
  };
}
let root; // 根元素
let createParent; // 当前元素父亲
// 数据结构 栈
let stack = [];
function start(tag, attrs) {
  // 开始标签
  // console.log('开始标签', tag, attrs)
  let element = createAstElement(tag, attrs);
  if (!root) {
    root = element;
  }
  createParent = element;
  stack.push(element);
}

function charts(text) {
  // 获取文本
  // console.log('文本', text)
  text = text.replace(/\s/g, ""); // 去掉空格
  if (text) {
    createParent.children.push({
      type: 3,
      text,
    });
  }
}

function end(tag) {
  // 结束标签
  // console.log('结束标签', tag)
  let element = stack.pop(); // 获取最后一个元素
  createParent = stack[stack.length - 1];
  if (createParent) {
    element.parent = createParent.tag;
    createParent.children.push(element);
  }
}

export function parseHTML(html) {
  // <div id="app">Hello Vue <h></h></div>
  while (html) {
    // html为空结束
    // 判断标签
    let textEnd = html.indexOf("<");
    if (textEnd === 0) {
      // (1) 开始标签
      const startTagMatch = parseStartTag(); // 开始标签内容
      if (startTagMatch) {
        start(startTagMatch.tagName, startTagMatch.attrs);
        continue;
      }
      // 结束标签
      let endTagMatch = html.match(endTag);
      if (endTagMatch) {
        // console.log(endTagMatch)
        advance(endTagMatch[0].length);
        end(endTagMatch[1]);
        continue;
      }
    }
    // 文本
    let text;
    if (textEnd > 0) {
      // 获取文本内容
      text = html.substring(0, textEnd);
      // console.log(text)
      if (text) {
        advance(text.length);
        charts(text);
      }
    }
  }
  function parseStartTag() {
    const start = html.match(startTagOpen); // 1返回结果 2false
    // console.log(start)
    if (start) {
      // 创建语法树
      let match = {
        tagName: start[1],
        attrs: [],
      };
      // 删除 开始标签
      advance(start[0].length);
      // 属性： 多个 遍历 注意结束标签>
      let attr;
      let end;
      while (
        !(end = html.match(startTagClose)) &&
        (attr = html.match(attribute))
      ) {
        // console.log(attr)
        match.attrs.push({
          name: attr[1],
          value: attr[3] || attr[4] || attr[5],
        });
        advance(attr[0].length);
        // break
      }
      if (end) {
        // console.log(end)
        advance(end[0].length);
        return match;
      }
    }
  }
  function advance(n) {
    html = html.substring(n);
    // console.log(html)
  }
  // console.log(root)
  return root;
}
